This invention relates generally to compiling executable programs, and more particularly relates to compiling executable programs to be compatible with previous versions of such programs.
A significant development in the computer programming field is that of object oriented programming. Object-oriented programming generally refers to computer programs, programming languages and tools which utilize the concept of xe2x80x9cobjects.xe2x80x9d The term xe2x80x9cobjectxe2x80x9d generally refers to an instance of a programmer-defined data structure (the data or variables of which are referred to as the object""s xe2x80x9cpropertiesxe2x80x9d) and functions that manipulate that structure (referred to as xe2x80x9cmember functions,xe2x80x9d xe2x80x9cmember procedures,xe2x80x9d or simply xe2x80x9cmembersxe2x80x9d of the object). In other words, objects are a combination of a data structure with a set of functions that perform methods on the data structure. The term xe2x80x9cclassxe2x80x9d generally refers to the definition of an object. Object concepts can be applied to programs formed with most any programming language, including C, Basic, and others. Various object-oriented programming languages, such as Microsoft Corporation""s Visual Basic version 4 programming environment, and the C++, and Smalltalk programming languages, provide formal syntax by which object-oriented concepts may be more easily expressed.
One benefit to the use of objects is that their members define a standard way for other programs to interact with or access the object""s properties. A set of semantically related functions implemented on an object is generally referred to as an xe2x80x9cinterfacexe2x80x9d of the object. Each object typically includes at least one interface, but in some object-oriented systems (such as OLE 2 described below) may include more than one interface. By allowing access to an object""s members through an interface, the object effectively xe2x80x9cexposesxe2x80x9d its functionality for use by other application programs. For example, a simple object with a property, xe2x80x9cColor,xe2x80x9d may have an interface which includes two members, xe2x80x9cGetColorxe2x80x9d and xe2x80x9cSetColor,xe2x80x9d which manipulate that property. Other application programs which have access to this object""s interface can make use of its functionality by calling the GetColor and SetColor members of that interface.
Microsoft Corporation""s Object Linking and Embedding 2 (xe2x80x9cOLE 2xe2x80x9d) provides a system for creating object-oriented applications for use with its Windows operating system. OLE 2 provides a way for objects supplied by one application program (hereafter referred to as the xe2x80x9cobject applicationxe2x80x9d or xe2x80x9cobject serverxe2x80x9d) to be controlled by another application program (hereafter referred to as a xe2x80x9ccontrolling applicationxe2x80x9d or xe2x80x9cclient applicationxe2x80x9d). After an object server is created, its programmer or developer can distribute the object server in the form of an executable file for use by others. Other developers and end users can then create client applications which make use of the functionality embodied in the object server""s objects by accessing those objects through their interfaces. Accordingly, OLE 2 provides a way for the functionality embodied in the object server to be useable by any number of client applications.
In order to access the interfaces of an object server, client applications are created by compiling the client applications using a specific version of the object server (i.e. xe2x80x9cbuilt againstxe2x80x9d an existing version of the object server which may have been distributed to the client application""s developer by the object application""s developer). When built against a specific object server, the client application will have embedded in it detailed assumptions about the set of interfaces that the object server supports, and the definition of those interfaces. For example, in OLE 2, interfaces to objects of an object server can be virtual function table interfaces or dispatch interfaces. An object implements a virtual function table interface by providing a virtual function table (vtable), which is an array containing pointers to members of the object such that the signatures of the members and their offsets within the vtable are exactly as specified in the definition of that interface. Members in the interface are accessed by client applications according to the particular offset of their function pointers within the vtable. More particularly, code is built into the client application which accesses a member by locating the function pointer at the member""s respective offset within the vtable, and issuing a call instruction to that function pointer. The assumption that the pointer to a member can be found at a particular vtable offset in the interface is thus embedded in the client application.
An object implements a dispatch interface by providing a dispatching interface (IDispatch) implementation whose xe2x80x9cinvokexe2x80x9d function supports a dispatch identifier (DISPID) to member mapping as specified by the interface""s definition. The IDispatch interface is implemented in conformance with the description in Corbett, et al., Method and System for Invoking Methods of an Object through a Dispatching Interface, U.S. Pat. No. 5,515,536 which is hereby incorporated by reference. Members in the interface are accessed by client applications according to their respective DISPIDs. More particularly, code is built into the client application which accesses a member by calling the invoke function and passing the member""s DISPID as an argument. The assumption that the DISPID will be mapped to the desired member is thus embedded in the client application.
Additionally, before a client application can begin accessing members within an interface, it must first gain access to the interface itself by obtaining a pointer to the interface. In OLE 2, object servers may provide a type library conforming to the description in U.S. patent application Ser. No. 07/959,056, entitled xe2x80x9cMethod and System for Interfacing to a Type Library,xe2x80x9d which is hereby incorporated by reference. The type library contains definitions of the classes of objects supplied by the object server and their interfaces.
So that client applications can get a pointer to interfaces on the object server""s objects, each object server registers information in a system registry provided in the operating system by which the classes that the object server supplies and their interfaces can be identified. This information includes a library identifier (library ID) associated with the object server""s type library and a unique class identifier (CLSID) associated with each of the classes it supplies, and also may include a unique interface identifier (IID) associated with each interface of the classes. In Microsoft Corporation""s Windows operating system, version 3.1, for example, object servers register their identifiers in a system registry that is maintained in a file named, xe2x80x9cREG.DAT,xe2x80x9d generally located in a directory with default name, xe2x80x9c WINDOWS.xe2x80x9d In Microsoft Corporation""s Windows NT operating system, object server identifiers are kept in a xe2x80x9cHKEY_CLASSES_ROOTxe2x80x9d section of a system registry maintained in the xe2x80x9c WINDOWS SYSTEM32 CONFIGxe2x80x9d directory.
OLE 2 further provides application programming interface (API) functions (e.g. CoCreateInstance and CoGetClassObject) which, given a CLSID, and IID passed in a call to the function, creates an object based on the definition of the class associated with the CLSID, and returns a pointer to the interface associated with the IID. Client applications obtain an initial pointer to an interface on an object with built-in code that calls such API functions with a CLSID to uniquely identify the object""s class in the system registry, and an IID that identifies the class"" interface. Accordingly, the assumption that the CLSID correctly identifies the class, and the IID correctly identifies the desired interface additionally is built into the client application.
Client applications also have embedded assumptions concerning the library ID associated with the object server""s type library. A specific library ID is associated with the type libraries for versions of an object server that supports a same set of service, i.e. a same set of CLSIDs and IIDs. Conversely, versions of an object server that don""t support an identical set of CLSIDs and IIDs have different library IDs assigned to their type libraries. By examining the library ID registered for a particular version of an object server (such as by calling a xe2x80x9cRegQueryKeyxe2x80x9d API function), client applications therefore can verify whether the object server version supports a desired set of CLSIDs and IIDs.
Because of these detailed assumptions that are built into client applications, there arises (in effect) a contractual agreement between an object server and its client applications that the object server""s interfaces have specific DISPIDS and vtable offsets for its members that will not change. Consequently, if any update or modification to an object server causes the DISPIDs or vtable offsets of its members to change, then the updated object server cannot support the same interfaces as its predecessor object server. When the updated object server fails to support one or more interfaces of the original version object server, the updated and original version object servers are said to lack version compatibility. Such version incompatibility means that client applications which were built against the original version object server (and therefore depend on the members having specific DISPIDs and vtable offsets in its interfaces) will be unable to access members of the updated object server and will cause errors in the attempt.
For example, when an object server named xe2x80x9cMyServerxe2x80x9d with a class named xe2x80x9cMyObjectxe2x80x9d having a member xe2x80x9cMyFunctionxe2x80x9d is built into an executable file (e.g. MyServer.exe), an interface is generated for MyObject in which MyFunction is assigned a unique vtable offset and DISPID. MyObject and its interface also are assigned a specific CLSID and IID, respectively. Any client applications built against MyServer are compiled into an executable program (e.g. MyApp.exe) which references MyFunction by the combination of MyObject""s CLSID and IID, and MyFunction""s DISPID. If MyServer is later modified and rebuilt so that MyFunction""s DISPID changes (due to removing MyFunction from MyObject or changing the definition of MyFunction), these previously built client applications will cause an invoke error when trying to call MyFunction by its prior IID/DISPID combination. Rebuilding the client applications against the new version of MyServer will rebind their MyFunction references to its new IID/DISPID combination. However, copies of the client applications that already are distributed to end users and installed on their machines will not be operable with the new object server.
A further problem with prior compilers is that the CLSIDs, IIDs, and DISPIDs of objects in the object servers have to be set and managed manually, such as with #define statements in an included header file. This places additional burdens on the programmer to manually track any changes to an object server which require corresponding changes to the CLSIDs and IIDs assigned to its objects, and manually update these identifiers.
One objective of the present invention, therefore, is to provide a compiler capable of automatically building an updated versions of an object server to be compatible with a previous version thereof when any differences in their source code permit.
A further objective of the invention is to detect differences in the source code of a revised object server from an existing version thereof that prevents the compiler from building the revised object server to be version compatible with the existing version, and notifying the object server""s developer that the revised object server cannot be compatible.
Another objective of the invention is to generate version numbers associated with each version of an object server which are indicative of the degree of compatibility between such versions of the object server.
Yet another objective of the invention is to automatically generate and control the library, class, interface, and dispatch identifiers of the object servers such that object server developers are not exposed to the identifiers of the object servers they create.
The present invention is a compiler and method for automatically compiling a program into a new object server so as to be version compatible with an existing object server. (A new versions of an object server is defined to be version compatible with its existing version when the new version""s classes are version compatible with those of the existing version. A new version of a class is version compatible its existing version if the new version supports all the interfaces of the existing version.) The invention includes version compatibility analysis of the program to detect any version incompatible differences from an existing version of the object server. If no version incompatible differences exist, the program is compiled into a version compatible object server which supports at least the interfaces supported by the existing object server. (For example, purely additive modifications from the existing object server, such as the addition of members without altering existing members, generally would not prevent the new object server from supporting the existing object server""s interfaces) Notification is provided if any difference is detected which prevents compiling a version compatible object server. Accordingly, a developer can upgrade an object server so as to fix bugs or incorporate additional functionality while retaining backward compatibility with client applications which were built against a previously distributed version of the object server. Although these client applications are unable to access the object server""s added functionality, the object server""s support for its previous version""s interfaces enables the client applications to interoperate with the upgraded object server and make use of functionality carried over from the previous version.
According to one feature of an exemplary embodiment of the invention, version compatibility analysis is performed by comparing the program against type information which was generated during compiling the existing object server and retained in a type library. The type library forms part of the existing object server""s executable program file (the existing object server""s xe2x80x9c.exexe2x80x9d file). Compiling a program to be version compatible with the existing object server is user-selectable, such as by setting a property of the new object server or a compiler option or parameter to specify the existing object server""s executable file.
According to another feature of the exemplary embodiment, when compiling the program into a new object server that is version compatible to the existing object server, identifiers and vtable offsets for the new object server""s classes are generated so as to be version compatible with those of the existing object server. In the type library of the new object server, each class for which there is a identically named class in the existing object server is assigned the same CLSID as was assigned to the identically named class in the existing object server. Further, the type library interface definitions for these classes that are identical to those of the identically named classes in the existing object server, with identical IIDs, as well as vtable offsets and DISPIDs. (CLSIDs, IIDs, DISPIDs, and vtable offsets are discussed in the Background of the Invention above.) Each of the CLSID, IIDs, vtable offsets, and DISPIDs are generated automatically for the new object server, without manual interaction, based on the type library of the existing object server. When the program is compiled into a new object server that is incompatible with the existing object server, new CLSIDs and IIDs are generated and assigned to the classes and interfaces of the new object server.
According to yet another feature of the exemplary embodiment, version numbers are associated with the type libraries of object servers and automatically updated to reflect an object server""s version compatibility relative to other versions of the object server. This enables client applications to determine the functionality provided by a particular version object server by testing its library""s version number. Each object server""s type library stores type information generated in compiling the object server, and is assigned a library identifier and a version number consisting of a major and a minor version value. The type libraries of version compatible object servers are assigned identical library IDs. When a newly compiled object server supports only new interfaces due to one or more version incompatible differences from an existing object server, the type library of the new object server is assigned a new library ID and a new version number (e.g. xe2x80x9c1.0xe2x80x9d) as if newly created. When the newly compiled object server supports each of the existing object server""s interfaces and one or more new interfaces, the type library of the new object server is assigned a library ID identical to that of the existing object server""s type library, and a version number whose minor version value is incremented in relation to that assigned to the existing object server""s type library. When the newly compiled object server supports only the same set of interfaces as the existing object server, the type library of the new object server is assigned a library ID and a version number identical to those of the existing object server""s type library.
Additional features and advantages of the invention will be made apparent from the following detailed description of a preferred embodiment which proceeds with reference to the accompanying drawings.